/*
**	Author:			Rob Valkass
**	Username:		rajv201
**	Date:			Tuesday 8th December 2009 CE
**
**	Name:			fractals
**
**	Description:	An application to generate Mandelbrot set fractal images
**					according to user-entered parameters and save them as bitmap
**					images (X PixMap format).
*/

#include <stdio.h>
#include <stdlib.h>

void printerror( char *message );
void printwarn( char *message );
void generatecolours( FILE *output, int n_colours );

int main()
{
	char buffer[25];
	int size = 0;
	int max_iterations = 0;
	float left = 0.0, right = 0.0, top = 0.0, bottom = 0.0;
	int n_colours = 0;
	FILE *image;

    printf("Welcome to the Fantastic Fractal Formulatoriser!\n");

	image = fopen("fractal.xpm", "w");

	if(image == NULL) {
		printerror("The output file could not be created/opened.");
		exit(1);
	}

    while(size <= 0) {
		printf("Please enter the width of the image in pixels: ");
		fgets(&buffer, sizeof(buffer), stdin);
		sscanf(buffer, "%d", &size);
		if(size <= 0)
			printerror("Please enter a positive integer.");
		if(size > 2000)
			printwarn("Large images take a long time to generate! Be warned!");
    }

	while(max_iterations <= 0) {
		printf("Please enter the iteration limit per pixel: ");
		fgets(&buffer, sizeof(buffer), stdin);
		sscanf(buffer, "%d", &max_iterations);
		if(max_iterations <= 0)
			printerror("Please enter a positive integer.");
		if(max_iterations > 1000)
			printwarn("Lots of iterations take a long time. Be warned!");
    }

	while(left == right || top == bottom) {
		printf("Please enter the co-ordinate area you want to generate\n");
		printf("using the format \"left right top bottom\": ");
		fgets(&buffer, sizeof(buffer), stdin);
		sscanf(buffer, "%f %f %f %f", &left, &right, &top, &bottom);

		if(left >= right || bottom >= top) {
			printerror("Those co-ordinates don't work. Please try again.");
			left = right = top = bottom = 0;
		}
	}

	while(n_colours == 0 || n_colours >= 1000) {
		printf("Please enter the number of colours to use: ");
		fgets(&buffer, sizeof(buffer), stdin);
		sscanf(buffer, "%d", &n_colours);
		if(n_colours <= 0)
			printerror("Please enter a positive integer.");
		if(n_colours >= 1000)
			printerror("The maximum number of colours is 999.");
	}

    fprintf(image, "! XPM2\n");
    fprintf(image, "%d %d %d 3\n", size, size, n_colours);

    generatecolours(image, n_colours);

    return 0;
}

void printerror( char *message ) {
	printf("%c[%d;%d;%dm%s%c[%d;%d;%dm\n", 0x1B, 1, 31, 40, message, 0x1B, 0, 37, 40);
}

void printwarn( char *message ) {
	printf("%c[%d;%d;%dm%s%c[%d;%d;%dm\n", 0x1B, 1, 33, 40, message, 0x1B, 0, 37, 40);
}

void generatecolours( FILE *output, int n_colours ) {
	int i = 0;
	int red, blue, green;

	for( i = 0; i < n_colours - 1; ++i )
	{
		if( i < (n_colours - 1)/6 )
		{
			red = 0;
			green = 255 - i%((n_colours - 1)/6) * (255 / ((n_colours - 1)/6));
			blue = 255;
		}
		else if( i < 2*(n_colours - 1)/6 )
		{
			red = i%((n_colours - 1)/6) * (255 / ((n_colours - 1)/6));
			green = 0;
			blue = 255;
		}
		else if( i < 3*(n_colours - 1)/6 )
		{
			red = 255;
			green = 0;
			blue = 255 - i%((n_colours - 1)/6) * (255 / ((n_colours - 1)/6));
		}
		else if( i < 4*(n_colours - 1)/6 )
		{
			red = 255;
			green = i%((n_colours - 1)/6) * (255 / ((n_colours - 1)/6));
			blue = 0;
		}
		else if( i < 5*(n_colours - 1)/6 )
		{
			red = 255 - i%((n_colours - 1)/6) * (255 / ((n_colours - 1)/6));
			green = 255;
			blue = 0;
		}
		else if( i < 6*(n_colours - 1)/6 )
		{
			red = 0;
			green = 255;
			blue = i%((n_colours - 1)/6) * (255 / ((n_colours - 1)/6));
		}

		fprintf(output, "%03d c #%02X%02X%02X\n", i, red, green, blue);
	}

	/* Add black for the inside of the Mandelbrot */
	fprintf(output, "%03d c #000000\n", n_colours - 1);
}
